<?php

namespace app\admin\server;

use Psr\SimpleCache\InvalidArgumentException;
use think\Cache;
use think\Exception;

class QyApiWeixinRedisServer
{
    const CGI_BIN_TAG_LIST = 'cgi_bin_tag_list'; //  获取标签列表
    const CGI_BIN_DEPARTMENT_USER_LIST = 'cgi_bin_department_user_list'; //  获取部门成员详情列表
    const CGI_BIN_TAG_GET = 'cgi_bin_tag_get'; //  根据 标签ID 获取标签成员
    const USER_ID_TAG = 'userid_tag'; // 根据 user_id 获取标签
    static $time_in_seconds = 60 * 30; // redis 过期时间

    /**
     * 设置：获取标签列表
     * @return true
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function setTagListRedis($time_in_seconds = 0)
    {
        !$time_in_seconds && $time_in_seconds = self::$time_in_seconds;
        try {
            $data = QyApiWeixinServer::getTagList();
            !$data && $data = [];
//            RedisServer::setStringRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_LIST, $data, $time_in_seconds);
            Cache::set(QyApiWeixinRedisServer::CGI_BIN_TAG_LIST, json_encode($data, JSON_UNESCAPED_UNICODE), $time_in_seconds);
            return true;
        } catch(Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取：获取标签列表
     * @return array|mixed|string
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function getTagListRedis()
    {
        try {
//            $data = RedisServer::getStringRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_LIST);
            $data = Cache::get(QyApiWeixinRedisServer::CGI_BIN_TAG_LIST, null);
            !empty($data) && $data = json_decode($data,true);
            if(empty($data)) {
                QyApiWeixinRedisServer::setTagListRedis();
                $data = Cache::get(QyApiWeixinRedisServer::CGI_BIN_TAG_LIST, null);
                $data = json_decode($data,true);
                !empty($data) && $data = json_decode($data,true);
            }
            if(empty($data)) {
                return $data;
            }
            return $data;
        } catch(Exception $e) {
            throw new Exception($e->getMessage());
        }
    }


    /**
     * 设置：根据 标签ID 获取标签成员
     * @param $tagid
     * @return true
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function setTagGetRedis($tagid, $time_in_seconds = 0)
    {
        !$time_in_seconds && $time_in_seconds = self::$time_in_seconds;
        try {
            $data = QyApiWeixinServer::getTagGet($tagid);
            empty($data) && $data = [];

            $result = Cache::get(QyApiWeixinRedisServer::CGI_BIN_TAG_GET, null);
            !empty($result) && $result = json_decode($result, true);
            if(empty($result)) {
                $result = [$tagid => $data];
            } else {
                $result[$tagid] = $data;
            }
            Cache::set(QyApiWeixinRedisServer::CGI_BIN_TAG_GET, json_encode($result), $time_in_seconds);
//            RedisServer::setHashRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_GET, $tagid, $data, $time_in_seconds);
            return true;
        } catch(Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取：根据 标签ID 获取标签成员
     * @return array|mixed|string
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function getTagGetRedis($tagid = '')
    {
        try {
//            $data = RedisServer::getHashRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_GET, $tagid);
            $data = Cache::get(QyApiWeixinRedisServer::CGI_BIN_TAG_GET);
            !empty($data) && $data = json_decode($data, true);
            if(empty($data)) {
                QyApiWeixinRedisServer::setTagGetRedis($tagid);
//                $data = RedisServer::getHashRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_GET, $tagid);
            } else {
                if(!isset($data[$tagid])) {
                    QyApiWeixinRedisServer::setTagGetRedis($tagid);
//                    $data = RedisServer::getHashRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_GET, $tagid);
                }
            }
            $data = Cache::get(QyApiWeixinRedisServer::CGI_BIN_TAG_GET,null);
            !empty($data) && $data = json_decode($data, true);

            if(!empty($data)){
                if(isset($data[$tagid])) {
                    return $data[$tagid];
                }
            }
            return  [];
        } catch(Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 协程 设置：根据 标签ID 获取标签成员  （协程   一次 获取所有的 标签成员）
     * @param $isWaitGroup @是否开启协程
     * @return void
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function setTagGetListRedis()
    {
        //同步最新数据
        set_time_limit(0);
        ini_set('memory_limit', '-1');
//        $isWaitGroup = env('CACHE.IS_WAIT_GROUP', false); // 是否开启协程
        $data = QyApiWeixinRedisServer::getTagListRedis();

        if($data) {
            $tag_total = count($data);
//            $tag_get_len = RedisServer::getLenRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_GET);
            $tag_get_len = RedisServer::getLenRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_GET);
            if(!$tag_get_len || $tag_total != $tag_get_len) {
                foreach($data as $item) {
                    QyApiWeixinRedisServer::getTagGetRedis($item['tagid']);
                }
            }
        }
        return true;
    }

    /**
     * 设置：  根据user_id 获取标签
     * @return true
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function setUserIdTagRedis($time_in_seconds = 0) // userid_tag
    {
        !$time_in_seconds && $time_in_seconds = self::$time_in_seconds;
        try {
            self::setTagGetListRedis();
            $result = self::getTagGetRedis();
            if($result) {
                $data = [];

                foreach($result as $tagid => $item) {
                    if($item['userlist']) {
                        foreach($item['userlist'] as $userlist) {
                            $tag = [];
                            $tag[$tagid] = [
                                'tagid'   => $tagid,
                                'tagname' => $item['tagname'],
                            ];
                            $_item = [
                                'name'      => $userlist['name'],
                                'userid'    => $userlist['userid'],
                                'tag'       => $tag,
                                'partylist' => $item['partylist']
                            ];
                            if(isset($data[$userlist['userid']])) {
                                $data[$userlist['userid']]['tag'][$tagid] = [
                                    'tagid'   => $tagid,
                                    'tagname' => $item['tagname'],
                                ];
                                if($item['partylist']) {
                                    $data[$userlist['userid']]['partylist'] = array_merge($data[$userlist['userid']]['partylist'], $item['partylist']);
                                }
                            } else {
                                $data[$userlist['userid']] = $_item;
                            }
                        }
                    }
                }
                if($data) {
                    $_data = [];
                    foreach($data as $userid => $item) {
//                        RedisServer::setHashRedis(QyApiWeixinRedisServer::USER_ID_TAG, $userid, $item, $time_in_seconds);
                        $_data[$userid] = $item;
                    }
                    Cache::set(QyApiWeixinRedisServer::USER_ID_TAG, json_encode($_data, JSON_UNESCAPED_UNICODE), $time_in_seconds);
                }
            }
            return true;
        } catch(Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取：根据user_id 获取标签
     * @param $userid
     * @return array|mixed
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function getUserIdTagRedis($userid = '')
    {
        try {

            $data = QyApiWeixinRedisServer::getTagListRedis();
            $tag_total = count($data);
            $tag_get_len = RedisServer::getLenRedis(QyApiWeixinRedisServer::CGI_BIN_TAG_GET);
            if(!$tag_total || !$tag_get_len || $tag_total != $tag_get_len) {
                self::setTagGetListRedis();
            }
            $data = RedisServer::getHashRedis(QyApiWeixinRedisServer::USER_ID_TAG, $userid);
            if(!$data) {
                QyApiWeixinRedisServer::setUserIdTagRedis();
                $data = RedisServer::getHashRedis(QyApiWeixinRedisServer::USER_ID_TAG, $userid);
            }
            return $data;
        } catch(Exception $e) {
            throw new Exception($e->getMessage());
        }
    }


    /**
     * 设置：获取部门成员详情列表
     * @param     $department_id
     * @param int $fetch_child
     * @param     $time_in_seconds
     * @return true
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function setDepartmentUserRedis(int $department_id = 1, int $fetch_child = 1, $time_in_seconds = 0)
    {
        !$time_in_seconds && $time_in_seconds = self::$time_in_seconds;
        try {
            $data = QyApiWeixinServer::departmentUserList('', $department_id, $fetch_child);
            !$data && $data = [];
//            RedisServer::setHashRedis(QyApiWeixinRedisServer::CGI_BIN_DEPARTMENT_USER_LIST, $department_id . "_" . $fetch_child, $data, $time_in_seconds);
            $result = Cache::set(QyApiWeixinRedisServer::CGI_BIN_DEPARTMENT_USER_LIST, null);
            if(!empty($result)) {
                $result = json_decode($result, true);
                $result[$department_id . "_" . $fetch_child] = $data;
            }

            Cache::set(QyApiWeixinRedisServer::CGI_BIN_DEPARTMENT_USER_LIST, json_encode($result, JSON_UNESCAPED_UNICODE), $time_in_seconds);
            return true;
        } catch(Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取：获取部门成员详情列表
     * @param     $department_id
     * @param int $fetch_child
     * @return array|mixed|string
     * @throws Exception
     * @throws InvalidArgumentException
     */
    public static function getDepartmentUserRedis(int $department_id = 1, int $fetch_child = 1)
    {
        try {
//            $data = RedisServer::getHashRedis(QyApiWeixinRedisServer::CGI_BIN_DEPARTMENT_USER_LIST, $department_id . "_" . $fetch_child);
            $data = Cache::get(QyApiWeixinRedisServer::CGI_BIN_DEPARTMENT_USER_LIST, null);
            !empty($data) && $data = json_decode($data, true);
            if(empty($data)) {
                $data = QyApiWeixinServer::departmentUserList('', $department_id, $fetch_child);
//                RedisServer::getHashRedis(QyApiWeixinRedisServer::CGI_BIN_DEPARTMENT_USER_LIST, $department_id . "_" . $fetch_child);
            } else {
                if(!isset($result[$department_id . "_" . $fetch_child])) {
                    $data = QyApiWeixinServer::departmentUserList('', $department_id, $fetch_child);
                }
            }
            $result = Cache::get(QyApiWeixinRedisServer::CGI_BIN_DEPARTMENT_USER_LIST, null);
            !empty($result) && $result = json_decode($result, true);
            if(!empty($result)) {
                $result = json_decode($result, true);
                $data = $result[$department_id . "_" . $fetch_child];
            }
            return $data;
        } catch(Exception $e) {
            throw new Exception($e->getMessage());
        }
    }
}